//    Openbravo POS is a point of sales application designed for touch screens.
//    Copyright (C) 2007-2009 Openbravo, S.L.
//    http://www.openbravo.com/product/pos
//
//    This file is part of Openbravo POS.
//
//    Openbravo POS is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    Openbravo POS is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with Openbravo POS.  If not, see <http://www.gnu.org/licenses/>.

package com.openbravo.pos.util;

import java.math.BigDecimal;

import com.openbravo.format.Formats;

public class RoundUtils {
    
    /** Creates a new instance of DoubleUtils */
    private RoundUtils() {
    }
    
    public static Double round(Double dValue) {
    	if(dValue==null)
    		return null;
        double fractionMultiplier = Math.pow(10.0, Formats.getCurrencyDecimals());
        return Math.rint(dValue * fractionMultiplier) / fractionMultiplier;
    }
    
    public static int compare(double d1, double d2) { 
        return Double.compare(round(d1), round(d2));
    }   
    
    public static double getValue(Double value) {
        return value == null ? 0.0 : value.doubleValue();
    }
    
    private static final int DEF_DIV_SCALE = 10;   
    
    /**  
     * 提供精确的加法运算   
     * @param v1 被加数  
     * @param v2 加数  
     * @return 两个参数的和  
     */  
    public static double add(double v1, double v2) {   
        BigDecimal b1 = new BigDecimal(Double.toString(v1));   
        BigDecimal b2 = new BigDecimal(Double.toString(v2));   
        return b1.add(b2).doubleValue();   
    }   
    
    public static double add(double v1, double v2,double v3) {   
        BigDecimal b1 = new BigDecimal(Double.toString(v1));   
        BigDecimal b2 = new BigDecimal(Double.toString(v2));  
        BigDecimal b3 = new BigDecimal(Double.toString(v3)); 
        return b1.add(b2).add(b3).doubleValue();   
    } 
       
    /**  
     * 提供精确的减法运算   
     * @param v1 被减数  
     * @param v2 减数  
     * @return 两个参数的差  
     */  
    public static double substract(double v1, double v2) {   
        BigDecimal b1 = new BigDecimal(Double.toString(v1));   
        BigDecimal b2 = new BigDecimal(Double.toString(v2));   
        return b1.subtract(b2).doubleValue();   
    }   
       
    /**  
     * 提供精确的乘法运算  
     * @param v1 被乘数  
     * @param v2 乘数  
     * @return 两个参数的积  
     */  
    public static double multiply(double v1, double v2) {   
        BigDecimal b1 = new BigDecimal(Double.toString(v1));   
        BigDecimal b2 = new BigDecimal(Double.toString(v2));   
        return b1.multiply(b2).doubleValue();   
    }   
  
    public static double multiply(double v1, double v2,double v3) {   
        BigDecimal b1 = new BigDecimal(Double.toString(v1));   
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        BigDecimal b3 = new BigDecimal(Double.toString(v3));
        return b1.multiply(b2).multiply(b3).doubleValue();   
    } 
    
    /**  
     * 提供（相对）精确的除法运算,当发生除不尽的情况时,  
     * 精确到小数点以后10位,以后的数字四舍五入.  
     * @param v1 被除数  
     * @param v2 除数  
     * @return 两个参数的商  
     */  
    public static double divide(double v1, double v2) {   
        return divide(v1, v2, DEF_DIV_SCALE);   
    }   
  
    /**  
     * 提供（相对）精确的除法运算.  
     * 当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入.  
     *   
     * @param v1 被除数  
     * @param v2 除数  
     * @param scale 表示需要精确到小数点以后几位  
     * @return 两个参数的商  
     */  
    public static double divide(double v1, double v2, int scale) {   
        if (scale < 0) {   
            throw new IllegalArgumentException("The scale must be a positive integer or zero");   
        }   
           
        BigDecimal b1 = new BigDecimal(Double.toString(v1));   
        BigDecimal b2 = new BigDecimal(Double.toString(v2));   
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();   
    }   
  
    /**  
     * 提供精确的小数位四舍五入处理  
     * @param v 需要四舍五入的数字  
     * @param scale 小数点后保留几位  
     * @return 四舍五入后的结果  
     */  
    public static double round(double v, int scale) {   
        if (scale < 0) {   
            throw new IllegalArgumentException("The scale must be a positive integer or zero");   
        }   
           
        BigDecimal b = new BigDecimal(Double.toString(v));   
        BigDecimal one = new BigDecimal("1");   
        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();   
    }   

}
